package cn.source.zk.service.impl;

import cn.source.zk.domain.dto.DbAllIndicatorsDTO;
import cn.source.zk.domain.dto.DbAllIndicatorsSqlDTO;
import cn.source.zk.domain.result.DynamicTableDataResult;
import cn.source.zk.mapper.DBAllIndicatorsMapper;
import cn.source.zk.mapper.ZkSettingQueryFieldsMapper;
import cn.source.zk.service.IDBAllIndicatorsService;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DBAllIndicatorsServiceImpl implements IDBAllIndicatorsService {

    @Autowired
    private DBAllIndicatorsMapper dbAllIndicatorsMapper;

    @Autowired
    private ZkSettingQueryFieldsMapper zkSettingQueryFieldsMapper;

    // 定义静态数组并初始化
    public static final String[] ALL_TABLES;

    // 静态代码块：在类加载时执行
    static {
        ALL_TABLES = new String[]{
                "db_ihra", "db_ihrb", "db_ihrc",
                "db_uhra", "db_uhrb", "db_uhrc",
                "db_ihrja", "db_ihrjb", "db_ihrjc",
                "db_uhrja", "db_uhrjb", "db_uhrjc", "db_basedata"
        };
    }

    /**
     * 获取移调数据
     *
     * @param dbAllIndicatorsDTO
     * @return
     */
    @Override
    public List<Map<String, Object>> getTransposedData(DbAllIndicatorsDTO dbAllIndicatorsDTO) {
        // 首先拼接后缀
        String[] suffixedTables = ALL_TABLES;
        if (Objects.nonNull(dbAllIndicatorsDTO.getTableNameSuffix())) {
            suffixedTables = Arrays.stream(ALL_TABLES)
                    .map(tableName -> tableName + dbAllIndicatorsDTO.getTableNameSuffix())
                    .toArray(String[]::new);
        }

        log.info(Arrays.toString(suffixedTables));

        DbAllIndicatorsSqlDTO dbAllIndicatorsSqlDTO = new DbAllIndicatorsSqlDTO();
        dbAllIndicatorsSqlDTO.setTimedate(dbAllIndicatorsDTO.getTimedate());
        dbAllIndicatorsSqlDTO.setTdGuid(dbAllIndicatorsSqlDTO.getTdGuid());

        List<String> toRemove = Arrays.asList("XH", "tdGuid", "timedate");
        List<String> fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[12]);

        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[12]);
        log.info(JSON.toJSONString(dbAllIndicatorsSqlDTO));
        LinkedHashMap<String, Object> dbBaseData = dbAllIndicatorsMapper.getDbBaseData(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[0]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[0]);

        LinkedHashMap<String, Object> dbIhrA = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[1]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[1]);
        LinkedHashMap<String, Object> dbIhrB = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[2]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[2]);
        LinkedHashMap<String, Object> dbIhrC = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[3]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[3]);
        LinkedHashMap<String, Object> dbUhrA = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[4]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[4]);
        LinkedHashMap<String, Object> dbUhrB = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[5]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[5]);
        LinkedHashMap<String, Object> dbUhrC = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[6]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[6]);
        LinkedHashMap<String, Object> dbIhrJA = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[7]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[7]);
        LinkedHashMap<String, Object> dbIhrJB = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[8]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[8]);
        LinkedHashMap<String, Object> dbIhrJC = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[9]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[9]);
        LinkedHashMap<String, Object> dbUhrJA = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[10]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[10]);
        LinkedHashMap<String, Object> dbUhrJB = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        fieldsList = dbAllIndicatorsMapper.getFieldsList(suffixedTables[11]);
        fieldsList.removeAll(toRemove);
        dbAllIndicatorsSqlDTO.setFields(fieldsList);
        dbAllIndicatorsSqlDTO.setTableName(suffixedTables[11]);
        LinkedHashMap<String, Object> dbUhrJC = dbAllIndicatorsMapper.getHarmonic(dbAllIndicatorsSqlDTO);

        // 转换为有序的Entry列表
        List<Map.Entry<String, Object>> dbBaseDataEntry = new ArrayList<>(dbBaseData.entrySet());
        List<Map.Entry<String, Object>> dbIhrAEntry = new ArrayList<>(dbIhrA.entrySet());
        List<Map.Entry<String, Object>> dbIhrBEntry = new ArrayList<>(dbIhrB.entrySet());
        List<Map.Entry<String, Object>> dbIhrCEntry = new ArrayList<>(dbIhrC.entrySet());

        List<Map.Entry<String, Object>> dbUhrAEntry = new ArrayList<>(dbUhrA.entrySet());
        List<Map.Entry<String, Object>> dbUhrBEntry = new ArrayList<>(dbUhrB.entrySet());
        List<Map.Entry<String, Object>> dbUhrCEntry = new ArrayList<>(dbUhrC.entrySet());

        List<Map.Entry<String, Object>> dbIhrJAEntry = new ArrayList<>(dbIhrJA.entrySet());
        List<Map.Entry<String, Object>> dbIhrJBEntry = new ArrayList<>(dbIhrJB.entrySet());
        List<Map.Entry<String, Object>> dbIhrJCEntry = new ArrayList<>(dbIhrJC.entrySet());

        List<Map.Entry<String, Object>> dbUhrJAEntry = new ArrayList<>(dbUhrJA.entrySet());
        List<Map.Entry<String, Object>> dbUhrJBEntry = new ArrayList<>(dbUhrJB.entrySet());
        List<Map.Entry<String, Object>> dbUhrJCEntry = new ArrayList<>(dbUhrJC.entrySet());

        // 确定最大行数
        int maxFields = Math.max(Math.max(dbBaseDataEntry.size(), dbIhrAEntry.size()), dbUhrJAEntry.size());

        List<Map<String, Object>> result = new ArrayList<>();

        for (int i = 0; i < maxFields; i++) {
            Map<String, Object> row = new LinkedHashMap<>();

            // 处理表1
            addRowData(row, dbBaseDataEntry, i, "dbBaseDataEntry");

            addRowData(row, dbIhrAEntry, i, "dbIhrAEntry");
            addRowData(row, dbIhrBEntry, i, "dbIhrBEntry");
            addRowData(row, dbIhrCEntry, i, "dbIhrCEntry");

            addRowData(row, dbUhrAEntry, i, "dbUhrAEntry");
            addRowData(row, dbUhrBEntry, i, "dbUhrBEntry");
            addRowData(row, dbUhrCEntry, i, "dbUhrCEntry");

            addRowData(row, dbIhrJAEntry, i, "dbIhrJAEntry");
            addRowData(row, dbIhrJBEntry, i, "dbIhrJBEntry");
            addRowData(row, dbIhrJCEntry, i, "dbIhrJCEntry");

            addRowData(row, dbUhrJAEntry, i, "dbUhrJAEntry");
            addRowData(row, dbUhrJBEntry, i, "dbUhrJBEntry");
            addRowData(row, dbUhrJCEntry, i, "dbUhrJCEntry");

            result.add(row);
        }
        log.info(JSON.toJSONString(result));
        return result;
    }

    private void addRowData(Map<String, Object> row, List<Map.Entry<String, Object>> entries, int index, String tablePrefix) {
        if (index < entries.size()) {
            Map.Entry<String, Object> entry = entries.get(index);
            row.put(tablePrefix + "Field", entry.getKey());
            row.put(tablePrefix + "Value", entry.getValue());
        } else {
            row.put(tablePrefix + "Field", "");
            row.put(tablePrefix + "Value", "");
        }
    }

    public DynamicTableDataResult getAllTablesData(DbAllIndicatorsDTO dbAllIndicatorsDTO) {
        // 创建动态表数据结果对象
        DynamicTableDataResult result = new DynamicTableDataResult();

        // 从DTO中获取表名后缀、时间日期和tdGuid参数
        String tableNameSuffix = dbAllIndicatorsDTO.getTableNameSuffix() == null ? "" : dbAllIndicatorsDTO.getTableNameSuffix();
        String timedate = dbAllIndicatorsDTO.getTimedate();
        String tdGuid = dbAllIndicatorsDTO.getTdGuid();

        //  从settingQueryFields表中查询所有可显示的数据；（需要修改！）
        List<Map<String, Object>> maps = zkSettingQueryFieldsMapper.queryTableData();
        // 组成一个map集合，key是表名，value是字段集合  为了后边查询数据库方便；
        List<Map<String, List<Object>>> queryResults = convertToTableFieldMap(maps);
        // 循环处理集合
        for (Map<String, List<Object>> queryResult : queryResults) {
            DbAllIndicatorsSqlDTO dbAllIndicatorsSqlDTO = new DbAllIndicatorsSqlDTO();
            for (Map.Entry<String, List<Object>> stringListEntry : queryResult.entrySet()) {
                // 前端需要展示中文，但是查询数据库需要英文，这里在convertToTableFieldMap转换的时候将英文字段和中文字段拼接到一起了，
                // 使用 “,”逗号隔开，[0]是英文表名，[1]是中文表名
                String[] split = stringListEntry.getKey().split(",");

                // 准备查询数据库的数据
                // 使用英文表名+表后缀组成完整表名；
                dbAllIndicatorsSqlDTO.setTableName(split[0] + tableNameSuffix);
                // 处理的时候将字段名是List<object>,转换成List<String>
                List<String> stringList = stringListEntry.getValue().stream()
                        .map(Object::toString)
                        .collect(Collectors.toList());
                dbAllIndicatorsSqlDTO.setFields(stringList); // 设置字段集合
                dbAllIndicatorsSqlDTO.setTimedate(timedate); // 设置时间
                dbAllIndicatorsSqlDTO.setTdGuid(tdGuid); // 设置唯一键

                // 查询数据库
                LinkedHashMap<String, Object> dbBaseData = dbAllIndicatorsMapper.getDbBaseData(dbAllIndicatorsSqlDTO);
                // 将英文字段转换成中文
                LinkedHashMap<String, Object> stringObjectLinkedHashMap = convertMapKeysToChineseName(dbBaseData);
                // 调用结束后清除字段缓存
                // fieldMappingCache.clear();
                // 第一个参数是中文表名，第二个参数转换后的查询数据；
                result.addTableData(split[1], stringObjectLinkedHashMap);
            }

        }

        // 新增：处理列排序（如果提供了排序参数）
        if (dbAllIndicatorsDTO.getColumnOrder() != null && !dbAllIndicatorsDTO.getColumnOrder().isEmpty()) {
            result.setColumnOrder(dbAllIndicatorsDTO.getColumnOrder());
        }

        // 新增：处理列隐藏（如果提供了隐藏列参数）
        if (dbAllIndicatorsDTO.getHiddenColumns() != null && !dbAllIndicatorsDTO.getHiddenColumns().isEmpty()) {
            result.hideColumns(dbAllIndicatorsDTO.getHiddenColumns());
        }


        return result;
    }

    /**
     * 将查询结果转换为有序的表名-字段列表映射
     *
     * @param queryResults 查询结果列表，每个元素包含字段名和表名
     * @return 有序Map，key为表名，value为字段列表
     */
    public static List<Map<String, List<Object>>> convertToTableFieldMap(List<Map<String, Object>> queryResults) {
        // 使用LinkedHashMap保证有序
        Map<String, List<Object>> tableFieldMap = new LinkedHashMap<>();

        // 遍历查询结果
        for (Map<String, Object> row : queryResults) {
            // 获取字段名和表名
            Object fieldName = row.get("field_name"); // 假设第一个字段名为"fieldName"
            Object tableName = row.get("table_prefix"); // 假设第二个字段名为"tableName"
            Object tableCnName = row.get("table_cn_name");

            if (fieldName != null && tableName != null) {
                String tableNameStr = tableName.toString() + "," + tableCnName.toString();

                // 如果Map中不存在该表名，则创建一个新的List
                if (!tableFieldMap.containsKey(tableNameStr)) {
                    tableFieldMap.put(tableNameStr, new ArrayList<>());
                }

                // 将字段名添加到对应表名的List中
                tableFieldMap.get(tableNameStr).add(fieldName);
            }
        }

        // 将结果封装到List中，通常List中只有一个元素，除非你需要多个分组
        List<Map<String, List<Object>>> result = new ArrayList<>();
        result.add(tableFieldMap);

        return result;
    }

    // 缓存字段映射
    private Map<String, String> fieldMappingCache;

    /**
     * 获取所有字段映射（英文名 -> 中文名）
     */
    public Map<String, String> getAllFieldMappings() {
        if (fieldMappingCache == null) {
            initFieldMappingCache();
        }
        return fieldMappingCache;
    }


    /**
     * 初始化字段映射缓存
     */
    private void initFieldMappingCache() {
        // 从数据库获取字段映射
        List<Map<String, Object>> mappings = zkSettingQueryFieldsMapper.getFieldAndFieldCn();
        fieldMappingCache = new HashMap<>();

        for (Map<String, Object> mapping : mappings) {
            String englishName = (String) mapping.get("field_name");
            String chineseName = (String) mapping.get("field_cn_name");
            if (!fieldMappingCache.containsKey(englishName)) {
                fieldMappingCache.put(englishName, chineseName);
            }

        }
    }

    /**
     * 将Map的key从英文转换为中文
     */
    public LinkedHashMap<String, Object> convertMapKeysToChineseName(LinkedHashMap<String, Object> originalMap) {
        initFieldMappingCache();

        LinkedHashMap<String, Object> convertedMap = new LinkedHashMap<>();

        for (Map.Entry<String, Object> entry : originalMap.entrySet()) {
            String englishKey = entry.getKey();
            Object value = entry.getValue();

            // 获取中文名，如果没有映射则使用原始英文名
            String chineseKey = fieldMappingCache.getOrDefault(englishKey, englishKey);

            convertedMap.put(chineseKey, value);
        }

        return convertedMap;
    }
}
